home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_87 / devsb.pas < prev    next >
Pascal/Delphi Source File  |  1995-01-01  |  31KB  |  1,312 lines

  1. {****************************************************************************}
  2. {                                                                            }
  3. { MODULE:         DevSB                                                      }
  4. {                                                                            }
  5. { DESCRIPTION:    Device driver for the Sound Blaster sound card and         }
  6. {                 compatibles, including the Sound Blaster Pro, Sound        }
  7. {                 Booster, etc...                                            }
  8. {                 Uses both: DMA and timer polling.                          }
  9. {                                                                            }
  10. { AUTHOR:         Juan Carlos Arévalo                                        }
  11. {                                                                            }
  12. { MODIFICATIONS:  Nobody (yet ;-)                                            }
  13. {                                                                            }
  14. { HISTORY:        18-Oct-1992 Documentation. It doesn't allow the stereo     }
  15. {                             of the SB Pro yet.                             }
  16. {                 12-Nov-1992 SB Pro driver included. Speed-ups and fixes.   }
  17. {                                                                            }
  18. { (C) 1992 VangeliSTeam                                                      }
  19. {____________________________________________________________________________}
  20.  
  21. UNIT DevSB;
  22.  
  23. INTERFACE
  24.  
  25. CONST
  26.   SBDevID        = 'SBlaster-Mono';
  27.   DMASBDevID     = 'DMA-SB-Mono';
  28.   DMASBSterDevID = 'DMA-SB-Stereo';
  29.   DMASBMixDevID  = 'Mix-DMA-SB-Stereo';
  30.   DMASBMix2DevID = 'Mix2-DMA-SB-Stereo';
  31.  
  32. CONST
  33.   SbCmdTimeout : WORD    = 100;   { $10 DSP Command timeout.   }
  34.   SbSplTimeout : WORD    = 10;    { $10 DSP Parameter timeout. }
  35.  
  36.   SbStereoMix  : BYTE    = 2;     { Stereo mixing algorithm.          }
  37.  
  38.   SbProMixMasterVol : BYTE    = 255;   { Master volume of the SB Pro mixer.    }
  39.   SbProMixDACVol    : BYTE    = 255;   { DAC volume.                           }
  40.   SbProMixFMVol     : BYTE    = 255;   { FM music volume.                      }
  41.   SbProMixFilter    : BOOLEAN = FALSE; { TRUE = Activate SB Pro output filter. }
  42.  
  43.  
  44. PROCEDURE SBInit  (Hz: WORD);
  45. PROCEDURE SBEnd;
  46.  
  47.  
  48.  
  49.  
  50. IMPLEMENTATION
  51.  
  52. USES Dos,
  53.      SoundDevices, StrConst,
  54.      Kbd, Debugging, SoundBlaster, Hardware;
  55.  
  56.  
  57.  
  58.  
  59.  
  60. FUNCTION SBName : TDevName; FAR;
  61.   BEGIN
  62.     SBName := GetString(StrDevSBName);
  63.   END;
  64.  
  65. FUNCTION DMASBName : TDevName; FAR;
  66.   BEGIN
  67.     DMASBName := GetString(StrDevDMASBName);
  68.   END;
  69.  
  70. FUNCTION DMASBSterName : TDevName; FAR;
  71.   BEGIN
  72.     DMASBSterName := GetString(StrDevDMASBSterName);
  73.   END;
  74.  
  75. FUNCTION DMASBMixName : TDevName; FAR;
  76.   BEGIN
  77.     DMASBMixName := GetString(StrDevDMASBMixName);
  78.   END;
  79.  
  80. FUNCTION DMASBMix2Name : TDevName; FAR;
  81.   BEGIN
  82.     DMASBMix2Name := GetString(StrDevDMASBMix2Name);
  83.   END;
  84.  
  85.  
  86.  
  87.  
  88. {$L DEVSB}
  89.  
  90.  
  91.  
  92.  
  93. (******)
  94.  
  95. PROCEDURE SBInit(Hz: WORD);
  96.   BEGIN
  97.     SbRegInit;
  98.     CalcTimerData(Hz);
  99.     InitTimer;
  100.   END;
  101.  
  102.  
  103. PROCEDURE SBIntHandler; FAR; EXTERNAL;
  104.  
  105.  
  106. PROCEDURE SBChgHz(Hz: WORD); FAR;
  107.   BEGIN
  108.     CalcTimerData(Hz);
  109.     InitTimer;
  110.   END;
  111.  
  112. PROCEDURE DevPoll; FAR;
  113.   BEGIN
  114.   END;
  115.  
  116.  
  117.  
  118.  
  119. PROCEDURE SBEnd; 
  120.   BEGIN
  121.     SbRegDone;
  122.   END;
  123.  
  124.  
  125. CONST
  126.   SBData : TSoundDevice = (
  127.     DevID      : SBDevID;
  128.     DMA        : FALSE
  129.   );
  130.  
  131. (******)
  132.  
  133.  
  134.  
  135.  
  136. FUNCTION GetDMACount : WORD;
  137.   VAR
  138.     c : BYTE;
  139.   BEGIN
  140.     PORT[$0C] := 0;           {clear BYTE POINTER flip-flop TO lower BYTE}
  141.  
  142.     c := PORT[$03];
  143.     GetDMACount := c + 256*WORD(PORT[$03]);
  144.   END;
  145.  
  146.  
  147.  
  148. CONST
  149.   OldDMAIrq : POINTER = NIL;
  150.  
  151.   DMAPlacedInBuf : WORD = 0;
  152.  
  153. PROCEDURE DMAIrq; FAR; FORWARD;
  154. PROCEDURE DoDMA;       FORWARD;
  155.  
  156. {
  157.  
  158. FUNCTION LimitHz(Hz: WORD; Output: BOOLEAN);
  159.   BEGIN
  160.  
  161.     IF Hz < 4000 THEN Hz := 4000;
  162.     IF (NOT DoHiSpeed) OR (SbStereo AND NOT Sb16Detected) THEN
  163.       IF Hz > 23000 THEN Hz := 23000;
  164.  
  165.     LimitHz := Hz;
  166.   END;
  167.  
  168.  
  169.  
  170. FUNCTION CalcTimeConst(Hz: WORD) : BYTE;
  171.   VAR
  172.     TimeConst : BYTE;
  173.   BEGIN
  174.     Hz := LimitHz(Hz, TRUE);
  175.  
  176.     IF SbStereo AND NOT Sb16Detected THEN
  177.       BEGIN
  178.         TimeConst := Hi(65536 - 128000000 DIV Hz);
  179.         SoundHz   :=  500000 DIV (256 - WORD(TimeConst));
  180.       END
  181.     ELSE IF (NOT Sb16Detect) AND (NOT DoHiSpeed) THEN
  182.       BEGIN
  183.         TimeConst := 256 - 1000000 DIV Hz;
  184.         SoundHz   := 1000000 DIV (256 - WORD(TimeConst));
  185.       END
  186.     ELSE
  187.       BEGIN
  188.         TimeConst := Hi(65536 - 256000000 DIV Hz);
  189.         SoundHz   := 1000000 DIV (256 - WORD(TimeConst));
  190.       END;
  191.  
  192.     CalcTimeConst := TimeConst;
  193.  
  194.   END;
  195.  
  196.  
  197. FUNCTION CalcHz(tc: BYTE) : WORD;
  198.   VAR
  199.     TimeConst : BYTE;
  200.   BEGIN
  201.  
  202.     IF (NOT Sb16Detect) AND (NOT DoHiSpeed) THEN
  203.       IF SbStereo THEN
  204.         Hz :=  500000 DIV (256 - WORD(TimeConst))
  205.       ELSE
  206.         Hz := 1000000 DIV (256 - WORD(TimeConst))
  207.     ELSE
  208.       Hz := 1000000 DIV (256 - WORD(TimeConst));
  209.  
  210.     CalcHz := Hz;
  211.  
  212.   END;
  213. }
  214.  
  215.  
  216. FUNCTION DMASBGetRealFreq(Hz: WORD) : WORD; FAR;
  217.   VAR
  218.     i    : WORD;
  219.     NHz1 : WORD;
  220.     NHz2 : WORD;
  221.   BEGIN
  222.     IF Hz < 4000 THEN Hz := 4000;
  223.     IF (NOT DoHiSpeed) OR (SbStereo AND NOT Sb16Detected) THEN
  224.       IF Hz > 21800 THEN Hz := 21800;
  225.  
  226.     i := Hi(65536 - (256000000 DIV Hz));
  227.     NHz1 := 1000000 DIV (256 - i);
  228.     NHz2 := 1000000 DIV (256 - i - 1);
  229.  
  230.     IF ABS(INTEGER(NHz1 - Hz)) > ABS(INTEGER(NHz2 - Hz)) THEN NHz1 := NHz2;
  231.  
  232.     DMASBGetRealFreq := NHz1;
  233.   END;
  234.  
  235.  
  236. FUNCTION DMASBProGetRealFreq(Hz: WORD) : WORD; FAR;
  237.   VAR
  238.     i    : WORD;
  239.     NHz1 : WORD;
  240.     NHz2 : WORD;
  241.   BEGIN
  242.     IF Sb16Detected THEN
  243.       BEGIN
  244.         DMASBProGetRealFreq := DMASBGetRealFreq(Hz);
  245.         EXIT;
  246.       END;
  247.  
  248.     IF Hz < 4000 THEN Hz := 4000;
  249.     IF (NOT DoHiSpeed) OR SbStereo THEN
  250.       IF Hz > 21800 THEN Hz := 21800;
  251.  
  252.     i := Hi(65536 - (128000000 DIV Hz));
  253.     NHz1 :=  500000 DIV (256 - i);
  254.     NHz2 :=  500000 DIV (256 - i - 1);
  255.  
  256.     IF ABS(INTEGER(NHz1 - Hz)) > ABS(INTEGER(NHz2 - Hz)) THEN NHz1 := NHz2;
  257.  
  258.     DMASBProGetRealFreq := NHz1;
  259.   END;
  260.  
  261.  
  262. PROCEDURE DMASBCalcTimerData(Hz: WORD);
  263.   BEGIN
  264.     CalcTimerData(PeriodicHz);
  265.  
  266.     Hz := ActiveDevice^.GetRealFreqProc(Hz);
  267.  
  268.     IF SbStereo AND NOT Sb16Detected THEN
  269.       BEGIN
  270.         TimeConst := Hi(65536 - 128000000 DIV Hz);
  271.         SoundHz   :=  500000 DIV (256 - WORD(TimeConst));
  272.       END
  273.     ELSE
  274.       BEGIN
  275.         TimeConst := Hi(65536 - 256000000 DIV Hz);
  276.         SoundHz   := 1000000 DIV (256 - WORD(TimeConst));
  277.       END;
  278.   END;
  279.  
  280.  
  281.  
  282. FUNCTION  SbMonoDetect : BOOLEAN; FAR;
  283.   BEGIN
  284.     SbRegInit;
  285.     SbProInit;
  286.     Sb16Init;
  287.     SbMonoDetect := SbRegDetect;
  288.   END;
  289.  
  290.  
  291. FUNCTION  SbStereoDetect : BOOLEAN; FAR;
  292.   BEGIN
  293.     SbRegInit;
  294.     SbProInit;
  295.     Sb16Init;
  296.     SbStereoDetect := SbProDetect OR Sb16Detect;
  297.   END;
  298.  
  299.  
  300.  
  301. PROCEDURE DMASBInit(Hz: WORD);
  302.   BEGIN
  303.     SbRegInit;
  304.     SbProInit;
  305.     Sb16Init;
  306.  
  307.     IF OldDMAIrq = NIL THEN BEGIN
  308.       OldDMAIrq := SetIRQVector(SbIrq, @DMAIrq);
  309.       EnableIRQ(SbIrq);
  310.     END;
  311.  
  312.     DMASet(SbDMAChan, $58, DMABuffer, DMABufferSize);
  313.  
  314.     SbProSetStereo(SbStereo);
  315.     DMASBCalcTimerData(Hz);
  316.     InitTimer;
  317.  
  318.     SbUpdateTimeConst;
  319.  
  320.     DMAStopped := FALSE;
  321.     DMAStop    := FALSE;
  322.   END;
  323.  
  324.  
  325. PROCEDURE DMASBMonoInit(Hz: WORD); FAR;
  326.   BEGIN
  327.     SbStereo := FALSE;
  328.     Sb16Bit  := FALSE;
  329.     DMASbInit(Hz);
  330.   END;
  331.  
  332.  
  333. PROCEDURE DMASBSterInit(Hz: WORD); FAR;
  334.   BEGIN
  335.     SbStereo    := TRUE;
  336.     Sb16Bit     := FALSE;
  337.     SbStereoMix := 0;
  338.     DMASbInit(Hz);
  339.   END;
  340.  
  341.  
  342. PROCEDURE DMASBMixInit(Hz: WORD); FAR;
  343.   BEGIN
  344.     SbStereo    := TRUE;
  345.     Sb16Bit     := FALSE;
  346.     SbStereoMix := 1;
  347.     DMASbInit(Hz);
  348.   END;
  349.  
  350.  
  351. PROCEDURE DMASBMix2Init(Hz: WORD); FAR;
  352.   BEGIN
  353.     SbStereo    := TRUE;
  354.     Sb16Bit     := FALSE;
  355.     SbStereoMix := 2;
  356.     DMASbInit(Hz);
  357.   END;
  358.  
  359.  
  360. PROCEDURE DMASBChgHz(Hz: WORD); FAR;
  361.   BEGIN
  362.     DMASBCalcTimerData(Hz);
  363.   END;
  364.  
  365.  
  366. PROCEDURE DMASBEnd; FAR;
  367.   BEGIN
  368.  
  369.     IF OldDMAIrq <> NIL THEN BEGIN
  370.       DMAStopped := FALSE;
  371.       DMAStop    := TRUE;
  372.  
  373.       ASM PUSHF; STI END;
  374.  
  375.       WHILE (NOT DMAStopped) AND (NOT DeviceIdling) DO;
  376.  
  377.       ASM POPF END;
  378.  
  379.       SetIRQVector(SbIrq, OldDMAIrq);
  380.       OldDMAIrq := NIL;
  381.     END;
  382.     DisableIRQ(SbIrq);
  383.   END;
  384.  
  385.  
  386.  
  387.  
  388. (*
  389. PROCEDURE DMAXchgBuffs; ASSEMBLER;
  390.   ASM
  391.                 MOV     DX,WORD PTR [DMABuffer1+2]
  392.                 MOV     SI,WORD PTR [DMABuffer1]
  393.                 MOV     BX,WORD PTR [DMABuffer1Full]
  394.                 LES     DI,         [DMABuffer2]
  395.                 MOV     AX,WORD PTR [DMABuffer2Full]
  396.                 MOV     WORD PTR [DMABuffer1],DI
  397.                 MOV     WORD PTR [DMABuffer1+2],ES
  398.                 MOV     WORD PTR [DMABuffer1Full],AX
  399.                 MOV     WORD PTR [DMABuffer2],SI
  400.                 MOV     WORD PTR [DMABuffer2+2],DX
  401.                 MOV     WORD PTR [DMABuffer2Full],BX
  402.   END;
  403. *)
  404.  
  405.  
  406. (*
  407. PROCEDURE AdjustBufferPointers;
  408.   VAR
  409.     o : WORD;
  410.   BEGIN
  411.     o := DMAPlacedInBuf;
  412.     IF SbStereo THEN INC(o, o);
  413.     IF Sb16Bit  THEN INC(o, o);
  414.  
  415.     IF DMABuffer1 = DMABuffer THEN
  416.       DMABuffer2 := Ptr(SEG(DMABuffer^),OFS(DMABuffer^) + o)
  417.     ELSE
  418.       DMABuffer1 := Ptr(SEG(DMABuffer^),OFS(DMABuffer^) + o);
  419.   END;
  420. *)
  421.  
  422.  
  423. PROCEDURE Dump8Channels; FORWARD;
  424.  
  425.  
  426. PROCEDURE DMADoGetBuff; ASSEMBLER;
  427.   ASM
  428. {
  429.                 PUSH    0
  430.                 PUSH    0
  431.                 PUSH    $FF
  432.                 CALL    SetBorder
  433. }
  434.  
  435.                 CALL    DoGetBuffer
  436.  
  437.                 ADD     [DMAPlacedInBuf],AX
  438.  
  439. {
  440.                 PUSH    0
  441.                 PUSH    $FF
  442.                 PUSH    0
  443.                 CALL    SetBorder
  444.                 MOV     AX,[DMAPlacedInBuf]
  445. }
  446.  
  447.                 CMP     AX,10
  448.                 JNC     @@nofin
  449.  
  450. {
  451.                 XOR     AX,AX
  452.                 MOV     [DMAPlacedInBuf],AX
  453. }
  454.                 JMP     @@Fin1
  455.  
  456. @@nofin:
  457.  
  458.                 MOV     BL,[SbStereo]
  459.                 AND     BL,BL
  460.                 JZ      @@1
  461.                  ADD    AX,AX
  462. @@1:
  463.  
  464.                 PUSH    AX
  465.                 CALL    GetDMACount
  466.                 MOV     BX,DMABufferSize - 1
  467.                 SUB     BX,AX
  468.                 ADD     BX,WORD PTR [DMABuffer]
  469.                 MOV     CX,BX
  470.                 SUB     BX,WORD PTR [DMABufferPtr]
  471.                 JNC     @@5
  472.                  ADD    BX,DMABufferSize
  473. @@5:            POP     AX
  474.                 PUSH    AX
  475.                 SUB     BX,AX
  476.                 JNC     @@6
  477. {                 INC    [PleaseFallBack]}
  478.                  ADD    AX,BX
  479.                  JNZ    @@6
  480.  
  481. {                 DEC    [PleaseFallBack]}
  482.                  POP    AX
  483.                  PUSH   AX
  484. @@6:
  485.                 POP     BX
  486. {
  487.                 PUSH    AX
  488.                 MOV     BX,WORD PTR [DMABufferPtr]
  489.                 SUB     BX,CX
  490.                 JNC     @@7
  491.                  ADD    BX,DMABufferSize
  492. @@7:            POP     AX
  493.                 SUB     BX,AX
  494.                 JNC     @@8
  495.                  ADD    AX,BX
  496. @@8:
  497. }
  498.                 MOV     BL,[SbStereo]
  499.                 AND     BL,BL
  500.                 JZ      @@2
  501.                  SHR    AX,1
  502. @@2:
  503.                  JMP    Dump8Channels
  504. @@Fin1:
  505.   END;
  506.  
  507.  
  508.  
  509. PROCEDURE Dump8Channels; ASSEMBLER;
  510.   CONST
  511.     First : BOOLEAN = TRUE;
  512.   ASM
  513.                 MOV     DL,[First]
  514.                 AND     DL,DL
  515.                 JZ      @@nofirst
  516.  
  517.                 MOV     WORD PTR [CS:@@Data11-2],0
  518.                 MOV     WORD PTR [CS:@@Data12-2],0
  519.                 MOV     WORD PTR [CS:@@Data21-2],0
  520.                 MOV     WORD PTR [CS:@@Data22-2],0
  521.                 MOV     [First],0
  522.  
  523. @@nofirst:
  524.                 MOV     DL,[DoEqualice]
  525.                 MOV     BYTE PTR [CS:@@Equalice],DL
  526.  
  527.                 MOV     BL,[SbStereo]
  528.                 MOV     BH,[SbStereoMix]
  529.                 LES     DI,[DMABufferPtr]
  530.                 MOV     CX,[DMABufferEnd]
  531.                 MOV     WORD PTR [CS:@@moData1-2],CX
  532.                 MOV     WORD PTR [CS:@@stData1-2],CX
  533.                 MOV     WORD PTR [CS:@@m1Data1-2],CX
  534.                 MOV     WORD PTR [CS:@@m2Data1-2],CX
  535.                 LDS     SI,[Sounding]
  536.                 CLD
  537.                 MOV     CX,AX
  538.                 AND     BL,BL
  539.                 JNZ     @@stereo
  540. @@lpfillmono:
  541.                  MOV    AX,[DS:SI]
  542.                  ADD    AX,[DS:SI+6]
  543.                  ADD    AX,[DS:SI+8]
  544.                  ADD    AX,[DS:SI+14]
  545.                  ADD    AX,[DS:SI+16]
  546.                  ADD    AX,[DS:SI+22]
  547.                  ADD    AX,[DS:SI+24]
  548.                  ADD    AX,[DS:SI+30]
  549.  
  550.                  MOV    BX,[DS:SI+2]
  551.                  ADD    BX,[DS:SI+4]
  552.                  ADD    BX,[DS:SI+10]
  553.                  ADD    BX,[DS:SI+12]
  554.                  ADD    BX,[DS:SI+18]
  555.                  ADD    BX,[DS:SI+20]
  556.                  ADD    BX,[DS:SI+26]
  557.                  ADD    BX,[DS:SI+28]
  558.  
  559.                  ADD    AX,BX
  560.                  JNO    @@nooverf
  561.                  JS     @@posit
  562.                   MOV   AX,-32768
  563.                  JMP    @@nooverf
  564. @@posit:          MOV   AX,32767
  565. @@nooverf:
  566.  
  567.  
  568.  
  569.  
  570.         MOV     DL,BYTE PTR [CS:@@Equalice]
  571.         AND     DL,DL
  572.         JZ      @@noequal
  573.  
  574.         PUSH    CX
  575.  
  576.         PUSH    AX
  577.  
  578.         CWD
  579.  
  580.         MOV     BX,1234
  581. @@Data11:
  582.         MOV     CX,1234
  583. @@Data12:
  584.  
  585.         SAR     CX,1
  586.         RCR     BX,1
  587.         SAR     CX,1
  588.         RCR     BX,1
  589.         SUB     AX,BX
  590.         SBB     DX,CX
  591.  
  592.         SAR     CX,1
  593.         RCR     BX,1
  594.         SUB     AX,BX
  595.         SBB     DX,CX
  596.  
  597.         MOV     WORD PTR [CS:@@Data11-2],AX
  598.         MOV     WORD PTR [CS:@@Data12-2],DX
  599.  
  600.         MOV     BX,AX
  601.         MOV     CX,DX
  602.  
  603.         POP     AX
  604.  
  605.         PUSH    BX
  606.         PUSH    CX
  607.  
  608.         CWD
  609.  
  610.         MOV     BX,1234
  611. @@Data21:
  612.         MOV     CX,1234
  613. @@Data22:
  614.  
  615.         SAR     CX,1
  616.         RCR     BX,1
  617.         ADD     AX,BX
  618.         ADC     DX,CX
  619.  
  620.         SAR     CX,1
  621.         RCR     BX,1
  622.         ADD     AX,BX
  623.         ADC     DX,CX
  624.  
  625.         SAR     CX,1
  626.         RCR     BX,1
  627.         SAR     CX,1
  628.         RCR     BX,1
  629.         ADD     AX,BX
  630.         ADC     DX,CX
  631.  
  632.         MOV     WORD PTR [CS:@@Data21-2],AX
  633.         MOV     WORD PTR [CS:@@Data22-2],DX
  634.  
  635.         POP     CX
  636.         POP     BX
  637.  
  638.         SUB     AX,BX
  639.         SBB     DX,CX
  640.         SUB     AX,BX
  641.         SBB     DX,CX
  642.  
  643.         SAR     DX,1
  644.         RCR     AX,1
  645.  
  646.         CMP     DX,0
  647.         JG      @@up
  648.         JNE     @@neg
  649.         CMP     AX,32768
  650.         JC      @@nada
  651. @@up:    MOV    AX,32767
  652.          JMP    @@nada
  653. @@neg:  CMP     DX,-1
  654.         JNZ     @@dw
  655.         CMP     AX,32768
  656.         JNC     @@nada
  657. @@dw:    MOV    AX,-32768
  658. @@nada:
  659.  
  660.         POP     CX
  661.  
  662. @@noequal:
  663.  
  664.  
  665.  
  666.  
  667.  
  668. (*
  669.  
  670.         MOV     DX,AX
  671.         MOV     BX,1234
  672.         NEG     BX
  673. @@Data1:
  674.         ADD     AX,BX
  675.                  JNO    @@1nooverf
  676.                  JS     @@1posit
  677.                   MOV   AX,-32767
  678.                  JMP    @@1nooverf
  679. @@1posit:         MOV   AX,32767
  680. @@1nooverf:
  681. {        MOV     WORD PTR [CS:@@Data1-2],AX}
  682.         XCHG    AX,DX
  683.  
  684.         MOV     BX,1234
  685. @@Data2:
  686.         ADD     AX,BX
  687.                  JNO    @@2nooverf
  688.                  JS     @@2posit
  689.                   MOV   AX,-32767
  690.                  JMP    @@2nooverf
  691. @@2posit:         MOV   AX,32767
  692. @@2nooverf:
  693. {        MOV     WORD PTR [CS:@@Data2-2],AX}
  694.  
  695.         SUB     AX,DX
  696.                  JNO    @@3nooverf
  697.                  JS     @@3posit
  698.                   MOV   AX,-32767
  699.                  JMP    @@3nooverf
  700. @@3posit:         MOV   AX,32767
  701. @@3nooverf:
  702.  
  703.         NEG     DX
  704.         ADD     AX,DX
  705.                  JNO    @@4nooverf
  706.                  JS     @@4posit
  707.                   MOV   AX,-32767
  708.                  JMP    @@4nooverf
  709. @@4posit:         MOV   AX,32767
  710. @@4nooverf:
  711.         ADD     AX,DX
  712.                  JNO    @@5nooverf
  713.                  JS     @@5posit
  714.                   MOV   AX,-32767
  715.                  JMP    @@5nooverf
  716. @@5posit:         MOV   AX,32767
  717. @@5nooverf:
  718.  
  719. *)
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.  
  727.                  XOR    AH,80h
  728.                  MOV    AL,AH
  729.                  STOSB
  730.                  CMP    DI,$1234
  731. @@moData1:
  732.                  JB     @@monocont
  733.                   SUB   DI,DMABufferSize
  734. @@monocont:      ADD    SI,MaxChannels*2
  735.                  DEC CX
  736.                  JNZ @@lpfillmono
  737. {                 LOOP   @@lpfillmono}
  738.                 JMP     @@Fin
  739.  
  740.  
  741.  
  742. @@Equalice:     DB 0
  743.  
  744.  
  745.  
  746.  
  747.  
  748.  
  749. @@stereo:       AND     BH,BH
  750.                 JNZ     @@domix
  751. @@lpfillster:
  752.                  MOV    AX,[DS:SI]
  753.                  ADD    AX,[DS:SI+6]
  754.                  ADD    AX,[DS:SI+8]
  755.                  ADD    AX,[DS:SI+14]
  756.                  ADD    AX,[DS:SI+16]
  757.                  ADD    AX,[DS:SI+22]
  758.                  ADD    AX,[DS:SI+24]
  759.                  ADD    AX,[DS:SI+30]
  760.  
  761.                  MOV    BX,[DS:SI+2]
  762.                  ADD    BX,[DS:SI+4]
  763.                  ADD    BX,[DS:SI+10]
  764.                  ADD    BX,[DS:SI+12]
  765.                  ADD    BX,[DS:SI+18]
  766.                  ADD    BX,[DS:SI+20]
  767.                  ADD    BX,[DS:SI+26]
  768.                  ADD    BX,[DS:SI+28]
  769.  
  770.                  ADD     BX,BX
  771.                  JNO     @@stnooverf1
  772.                  JS      @@stposit1
  773.                   MOV    BX,-32768
  774.                  JMP     @@stnooverf1
  775. @@stposit1:       MOV    BX,32767
  776. @@stnooverf1:
  777.                  ADD     AX,AX
  778.                  JNO     @@stnooverf2
  779.                  JS      @@stposit2
  780.                   MOV    AX,-32768
  781.                  JMP     @@stnooverf2
  782. @@stposit2:       MOV    AX,32767
  783. @@stnooverf2:
  784.                  MOV    AL,BH
  785.                  XOR    AX,8080h
  786.                  STOSW
  787.                  CMP    DI,$1234
  788. @@stData1:
  789.                  JB     @@stercont
  790.                   SUB   DI,DMABufferSize
  791. @@stercont:      ADD    SI,MaxChannels*2
  792.                  LOOP   @@lpfillster
  793.                 JMP     @@Fin
  794.  
  795. @@domix:        DEC     BH
  796.                 JNZ     @@domix2
  797. @@lpfillmix1:
  798.                  MOV    AX,[DS:SI]
  799.                  ADD    AX,[DS:SI+6]
  800.                  ADD    AX,[DS:SI+8]
  801.                  ADD    AX,[DS:SI+14]
  802.                  ADD    AX,[DS:SI+16]
  803.                  ADD    AX,[DS:SI+22]
  804.                  ADD    AX,[DS:SI+24]
  805.                  ADD    AX,[DS:SI+30]
  806.  
  807.                  MOV    BX,[DS:SI+2]
  808.                  ADD    BX,[DS:SI+4]
  809.                  ADD    BX,[DS:SI+10]
  810.                  ADD    BX,[DS:SI+12]
  811.                  ADD    BX,[DS:SI+18]
  812.                  ADD    BX,[DS:SI+20]
  813.                  ADD    BX,[DS:SI+26]
  814.                  ADD    BX,[DS:SI+28]
  815.  
  816.                  MOV     DX,AX
  817.                  ADD     AX,BX
  818.                  JNO     @@m1nooverf0
  819.                   RCR    AX,1
  820.                  JMP     @@m1ovc0
  821. @@m1nooverf0:     SAR    AX,1
  822. @@m1ovc0:
  823.                  ADD     BX,AX
  824.                  JNO     @@m1nooverf1
  825.                  JS      @@m1posit1
  826.                   MOV    BX,-32768
  827.                  JMP     @@m1nooverf1
  828. @@m1posit1:       MOV    BX,32767
  829. @@m1nooverf1:
  830.                  ADD     AX,DX
  831.                  JNO     @@m1nooverf2
  832.                  JS      @@m1posit2
  833.                   MOV    AX,-32768
  834.                  JMP     @@m1nooverf2
  835. @@m1posit2:       MOV    AX,32767
  836. @@m1nooverf2:
  837.                  MOV    AL,BH
  838.                  XOR    AX,8080h
  839.                  STOSW
  840.                  CMP    DI,$1234
  841. @@m1Data1:
  842.                  JB     @@mix1cont
  843.                   SUB   DI,DMABufferSize
  844. @@mix1cont:      ADD    SI,MaxChannels*2
  845.                  LOOP   @@lpfillmix1
  846.                 JMP     @@Fin
  847.  
  848.  
  849.  
  850. @@domix2:
  851. @@lpfillmix2:
  852.                  MOV    AX,[DS:SI]
  853.                  ADD    AX,[DS:SI+6]
  854.                  ADD    AX,[DS:SI+8]
  855.                  ADD    AX,[DS:SI+14]
  856.                  ADD    AX,[DS:SI+16]
  857.                  ADD    AX,[DS:SI+22]
  858.                  ADD    AX,[DS:SI+24]
  859.                  ADD    AX,[DS:SI+30]
  860.  
  861.                  MOV    BX,[DS:SI+2]
  862.                  ADD    BX,[DS:SI+4]
  863.                  ADD    BX,[DS:SI+10]
  864.                  ADD    BX,[DS:SI+12]
  865.                  ADD    BX,[DS:SI+18]
  866.                  ADD    BX,[DS:SI+20]
  867.                  ADD    BX,[DS:SI+26]
  868.                  ADD    BX,[DS:SI+28]
  869.  
  870.  
  871.                  SAR     BX,1
  872.                  SAR     AX,1
  873.                  MOV     DX,AX
  874.                  ADD     AX,BX
  875.  
  876.                  MOV     [WORD PTR CS:@@datastm2-2],AX
  877.                  SAR     AX,1
  878.                  ADD     AX,1234
  879. @@datastm2:
  880.                  JNO     @@m2nooverf1
  881.                  JS      @@m2posit1
  882.                   MOV    AX,-32768
  883.                  JMP     @@m2nooverf1
  884. @@m2posit1:       MOV    AX,32767
  885. @@m2nooverf1:
  886.                  ADD     DX,AX
  887.                  JNO     @@m2nooverf2
  888.                  JS      @@m2posit2
  889.                   MOV    DX,-32768
  890.                  JMP     @@m2nooverf2
  891. @@m2posit2:       MOV    DX,32767
  892. @@m2nooverf2:
  893.                  ADD     AX,BX
  894.                  JNO     @@m2nooverf3
  895.                  JS      @@m2posit3
  896.                   MOV    AX,-32768
  897.                  JMP     @@m2nooverf3
  898. @@m2posit3:       MOV    AX,32767
  899. @@m2nooverf3:
  900.                  MOV    AL,DH
  901.                  XOR    AX,8080h
  902.                  STOSW
  903.                  CMP    DI,$1234
  904. @@m2Data1:
  905.                  JB     @@mix2cont
  906.                   SUB   DI,DMABufferSize
  907. @@mix2cont:      ADD    SI,MaxChannels*2
  908.                  LOOP   @@lpfillmix2
  909.  
  910. @@Fin:          MOV     AX,SEG(@Data)
  911.                 MOV     DS,AX
  912.                 MOV     WORD PTR [DMABufferPtr],DI
  913.  
  914. {
  915.                 PUSH    0
  916.                 PUSH    0
  917.                 PUSH    0
  918.                 CALL    SetBorder
  919. }
  920.   END;
  921.  
  922.  
  923.  
  924.  
  925. PROCEDURE DoDMA; ASSEMBLER;
  926.   CONST
  927.     OLDDMABP     : WORD = 0;
  928.     OLDDMACT     : WORD = 0;
  929.   ASM
  930.                 CLI
  931.  
  932.                 PUSH    BX
  933.                 PUSH    CX
  934.                 PUSH    DX
  935.                 PUSH    DI
  936.                 PUSH    SI
  937.                 PUSH    ES
  938. {
  939.                 CALL    GetDMACount
  940.                 INC     AX
  941.                 MOV     BX,[OLDDMACT]
  942.                 MOV     [OLDDMACT],AX
  943.                 SUB     BX,AX
  944.                 JNC     @@8
  945.                  ADD    BX,DMABufferSize
  946. @@8:
  947.                 PUSH    0
  948.                 PUSH    BX
  949.                 PUSH    $70
  950.                 CALL    WriteNum
  951.  
  952.                 MOV     BX,WORD PTR [DMABufferPtr]
  953.                 MOV     AX,[OLDDMABP]
  954.                 MOV     [OLDDMABP],BX
  955.                 SUB     BX,AX
  956.                 JNC     @@9
  957.                  ADD    BX,DMABufferSize
  958. @@9:
  959.                 PUSH    20
  960.                 PUSH    BX
  961.                 PUSH    $70
  962.                 CALL    WriteNum
  963. }
  964.  
  965.                 PUSHA
  966.                 PUSH    'l'
  967.                 PUSH    $02
  968.                 CALL    WriteChar
  969.                 POPA
  970.  
  971.                 MOV     AX,[DMAPlacedInBuf]
  972.                 AND     AX,AX
  973.                 JNZ     @@haybuf
  974.  
  975.                 INC     [PleaseFallBack]
  976.  
  977.                 PUSHA
  978.                 PUSH    'd'
  979.                 PUSH    $70
  980.                 CALL    WriteChar
  981.                 POPA
  982.  
  983.                 CALL    DMADoGetBuff
  984.  
  985.                 CALL    DMADoGetBuff
  986.  
  987.                 MOV     AX,[DMAPlacedInBuf]
  988.                 AND     AX,AX
  989.                 JNZ     @@haybuf
  990.                  INC    AH
  991.                  MOV    [DeviceIdling],AH
  992.                  JMP    @@Fin
  993.  
  994. @@haybuf:       XOR     BH,BH
  995.                 MOV     [DeviceIdling],BH
  996.  
  997.                 CALL    SbUpdateTimeConst
  998.  
  999.                 MOV     CX,[DMAPlacedInBuf]
  1000.                 PUSH    CX
  1001.                 PUSH    1
  1002.                 CALL    SbPlaySample
  1003.  
  1004.                 XOR     AX,AX
  1005.                 MOV     [DMAPlacedInBuf],AX
  1006.  
  1007. @@7:
  1008.                 CALL    DMADoGetBuff
  1009.                 CALL    DMADoGetBuff
  1010.  
  1011. @@Fin:          POP     ES
  1012.                 POP     SI
  1013.                 POP     DI
  1014.                 POP     DX
  1015.                 POP     CX
  1016.                 POP     BX
  1017.   END;
  1018.  
  1019.  
  1020.  
  1021.  
  1022. PROCEDURE DMATim; FAR; ASSEMBLER;
  1023.   ASM
  1024.                 CLI
  1025.  
  1026.                 PUSH    AX
  1027.                 PUSH    DS
  1028.                 PUSH    ES
  1029.  
  1030.                 MOV     AX,SEG(@Data)
  1031.                 MOV     DS,AX
  1032.  
  1033.                 PUSHA
  1034.                 PUSH    't'
  1035.                 PUSH    $20
  1036.                 CALL    WriteChar
  1037.                 POPA
  1038.  
  1039.                 MOV     AL,[DMAIrqWatch]
  1040.                 CMP     AL,20
  1041.                 JNC     @@dowatch
  1042.  
  1043.                 MOV     AL,[DeviceIdling]
  1044.                 AND     AL,AL
  1045.                 JZ      @@notneeded
  1046.  
  1047.                 PUSHA
  1048.                 CALL    InitTimer
  1049.                 POPA
  1050.  
  1051.                 JMP     @@noack
  1052. @@dowatch:
  1053.                 PUSH    DX
  1054.                 MOV     DX,[DSP8AckPort]
  1055.                 IN      AL,DX
  1056.                 MOV     DX,[DSPLifePort]
  1057.                 IN      AL,DX
  1058.                 POP     DX
  1059.  
  1060. @@noack:        MOV     AL,[DMAStop]
  1061.                 AND     AL,AL
  1062.                 JZ      @@notstop
  1063.  
  1064.                 MOV     [DMAStopped],AL
  1065.                 MOV     [DeviceIdling],AL
  1066.                 JMP     @@notneeded
  1067.  
  1068. @@notstop:      XOR     AL,AL
  1069.                 MOV     [DeviceIdling],AL
  1070.  
  1071.                 CALL    DoDMA
  1072.  
  1073.                 XOR     AL,AL
  1074.                 MOV     [DMAIrqWatch],AL
  1075.                 
  1076. @@notneeded:    MOV     AL,[DMAIrqWatch]
  1077.                 CMP     AL,100
  1078.                 JNC     @@noinc
  1079.  
  1080.                 INC     [DMAIrqWatch]
  1081.  
  1082. @@noinc:        MOV     AX,[SystemClockIncr]
  1083.                 ADD     [SystemClockCount],AX
  1084.                 JNC     @@nosys
  1085.  
  1086.                 PUSHF
  1087.                 CALL    CSOldInt8
  1088.                 JMP     @@sisys
  1089.  
  1090. @@nosys:        MOV     AL,20h
  1091.                 OUT     20h,AL
  1092.  
  1093. @@sisys:        STI
  1094.  
  1095.                 MOV     AL,[DMAStop]
  1096.                 AND     AL,AL
  1097.                 JZ      @@notstop2
  1098.  
  1099.                 MOV     [DMAStopped],AL
  1100.                 MOV     [DeviceIdling],AL
  1101.                 JMP     @@donothing
  1102.  
  1103. @@notstop2:     PUSHA
  1104.                 CALL    PeriodicProc
  1105.                 MOV     AX,[DMAPlacedInBuf]
  1106.                 AND     AX,AX
  1107.                 JNZ     @@nogetbuff
  1108.  
  1109.                 CLI
  1110.                 CALL    DMADoGetBuff
  1111.                 STI
  1112.  
  1113. @@nogetbuff:
  1114.                 POPA
  1115.  
  1116. @@donothing:
  1117.                 POP     ES
  1118.                 POP     DS
  1119.                 POP     AX
  1120.                 IRET
  1121.   END;
  1122.  
  1123. PROCEDURE DMAIrq; ASSEMBLER;
  1124.   CONST
  1125.     Old83 : BYTE = 0;
  1126.   ASM
  1127.                 CLI
  1128.  
  1129.                 PUSH    DX
  1130.                 PUSH    AX
  1131.                 PUSH    DS
  1132.                 PUSH    ES
  1133.  
  1134.                 MOV     AX,SEG(@Data)
  1135.                 MOV     DS,AX
  1136. {
  1137.                 MOV     DX,[MixAddrPort]
  1138.                 MOV     AL,$83
  1139.                 OUT     DX,AL
  1140.                 INC     DL
  1141.                 IN      AL,DX
  1142.                 MOV     [Old83],AL
  1143.                 DEC     DL
  1144.  
  1145.                 MOV     AL,$83
  1146.                 OUT     DX,AL
  1147.                 INC     DL
  1148.                 XOR     AL,AL
  1149.                 OUT     DX,AL
  1150. }
  1151.                 MOV     DX,[DSP8AckPort]
  1152.                 IN      AL,DX
  1153.  
  1154.                 MOV     DX,[DSPLifePort]
  1155.                 IN      AL,DX
  1156.  
  1157.  
  1158.                 PUSHA
  1159.                 PUSH    'i'
  1160.                 PUSH    $07
  1161.                 CALL    WriteChar
  1162.                 POPA
  1163.  
  1164.                 XOR     AL,AL
  1165.                 MOV     [DMAIrqWatch],AL
  1166.  
  1167.                 MOV     AL,[DMAStop]
  1168.                 AND     AL,AL
  1169.                 JZ      @@nostop
  1170.  
  1171.                 MOV     [DMAStopped],AL
  1172.                 MOV     [DeviceIdling],AL
  1173.                 JMP     @@Fin
  1174. @@nostop:
  1175.                 CALL    DoDMA
  1176. @@Fin:
  1177. {
  1178.                 PUSHA
  1179.                 PUSH    100
  1180.                 PUSH    $DA
  1181.                 CALL    SbWriteByte
  1182.                 POPA
  1183.  
  1184.                 PUSHA
  1185.                 PUSH    100
  1186.                 PUSH    $45
  1187.                 CALL    SbWriteByte
  1188.                 POPA
  1189. }
  1190. {
  1191.                 MOV     DX,[MixAddrPort]
  1192.                 MOV     AL,$83
  1193.                 OUT     DX,AL
  1194.                 INC     DL
  1195.                 MOV     AL,[Old83]
  1196.                 OUT     DX,AL
  1197. }
  1198.                 MOV     AX,[SbIrq]
  1199.                 CMP     AL,10
  1200.                 JNZ     @@not10
  1201.  
  1202.                 MOV     AL,$20
  1203.                 OUT     $A0,AL
  1204.  
  1205. @@not10:        MOV     AL,$20
  1206.                 OUT     $20,AL
  1207.  
  1208.                 POP     ES
  1209.                 POP     DS
  1210.                 POP     AX
  1211.                 POP     DX
  1212.                 IRET
  1213.   END;
  1214.  
  1215.  
  1216. CONST
  1217.   DMASBData : TSoundDevice = (
  1218.     DevID      : DMASBDevID;
  1219.     DMA        : TRUE
  1220.   );
  1221.  
  1222.  
  1223. CONST
  1224.   DMASBSterData : TSoundDevice = (
  1225.     DevID      : DMASBSterDevID;
  1226.     DMA        : TRUE
  1227.   );
  1228.  
  1229.  
  1230. CONST
  1231.   DMASBMixData : TSoundDevice = (
  1232.     DevID      : DMASBMixDevID;
  1233.     DMA        : TRUE
  1234.   );
  1235.  
  1236.  
  1237. CONST
  1238.   DMASBMix2Data : TSoundDevice = (
  1239.     DevID      : DMASBMix2DevID;
  1240.     DMA        : TRUE
  1241.   );
  1242.  
  1243.  
  1244.  
  1245.  
  1246. (******)
  1247.  
  1248. BEGIN
  1249.  
  1250.   WITH SBData DO BEGIN
  1251.     Name            := SBName;
  1252.     AutoDetect      := SbRegDetect;
  1253.     InitRut         := SBInit;
  1254.     ChgHzProc       := SBChgHz;
  1255.     GetRealFreqProc := GetRealFreq;
  1256.     TimerHandler    := SBIntHandler;
  1257.     PollRut         := DevPoll;
  1258.     EndRut          := SBEnd;
  1259.   END;
  1260.  
  1261.   WITH DMASBData DO BEGIN
  1262.     Name            := DMASBName;
  1263.     AutoDetect      := SbMonoDetect;
  1264.     InitRut         := DMASBMonoInit;
  1265.     ChgHzProc       := DMASBChgHz;
  1266.     GetRealFreqProc := DMASBGetRealFreq;
  1267.     TimerHandler    := DMATim;
  1268.     PollRut         := DevPoll;
  1269.     EndRut          := DMASBEnd;
  1270.   END;
  1271.  
  1272.   WITH DMASBSterData DO BEGIN
  1273.     Name            := DMASBSterName;
  1274.     AutoDetect      := SbStereoDetect;
  1275.     InitRut         := DMASBSterInit;
  1276.     ChgHzProc       := DMASBChgHz;
  1277.     GetRealFreqProc := DMASBProGetRealFreq;
  1278.     TimerHandler    := DMATim;
  1279.     PollRut         := DevPoll;
  1280.     EndRut          := DMASBEnd;
  1281.   END;
  1282.  
  1283.   WITH DMASBMixData DO BEGIN
  1284.     Name            := DMASBMixName;
  1285.     AutoDetect      := SbStereoDetect;
  1286.     InitRut         := DMASBMixInit;
  1287.     ChgHzProc       := DMASBChgHz;
  1288.     GetRealFreqProc := DMASBProGetRealFreq;
  1289.     TimerHandler    := DMATim;
  1290.     PollRut         := DevPoll;
  1291.     EndRut          := DMASBEnd;
  1292.   END;
  1293.  
  1294.   WITH DMASBMix2Data DO BEGIN
  1295.     Name            := DMASBMix2Name;
  1296.     AutoDetect      := SbStereoDetect;
  1297.     InitRut         := DMASBMix2Init;
  1298.     ChgHzProc       := DMASBChgHz;
  1299.     GetRealFreqProc := DMASBProGetRealFreq;
  1300.     TimerHandler    := DMATim;
  1301.     PollRut         := DevPoll;
  1302.     EndRut          := DMASBEnd;
  1303.   END;
  1304.  
  1305.   InitDevice(@DMASBMix2Data);
  1306.   InitDevice(@DMASBMixData);
  1307.   InitDevice(@DMASBSterData);
  1308.   InitDevice(@DMASBData);
  1309.   InitDevice(@SBData);
  1310.  
  1311. END.
  1312.